<?php

if (!defined('TOBBIVM'))
	header('location:/template/notrepassing.php');
/**
 * This file is part of TobbiVMShop.
 *
 * TobbiVMShop is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * TobbiVMShop is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with TobbiVMShop.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Backup and restore a mysql-database. 
 * Send backup-file via email and restore database via
 * uploaded backup-file
 *
 * @author Norbert Gebert
 * @copyright Norbert Gebert 01.04.2015
 * @license GPL3
 *
 * @version 0.5b
 * @package Admin
 * @subpackage global
 */
class backup extends db
{

	private static $_compression = 1;
	private static $_path = 'backup';
	private static $_filetype = 'sql';
	private static $_cur_time;
	private static $_cur_date;
	private static $_dbName = DB_NAME;
	private static $_file;
	private static $_filename;

	/**
	 * Set default values
	 */
	function __construct()
	{
		$compression = 1;

		// If we can't use gzip, gzip = 0
		if (!extension_loaded('zlib'))
			self::$_compression = 0;

		if ($compression == 1)
			self::$_filetype = 'sql.gz';

		if ($compression == 0)
			self::$_filetype = 'sql';
	}

	/**
	 * Starts the db-backup
	 */
	public static function startBackup()
	{
		// If possible 'timeout' to prevent
		if (!ini_get('safe_mode'))
			set_time_limit(300);

		self::$_cur_time = date("H-i_d.m.Y");
		self::$_cur_date = date("Y-m-d");

		// Create backup
		$newfile = "";
		$newfile_data = "";

		$tables = db::getInstance()->rawQuery("SHOW TABLES FROM " . self::$_dbName);

		foreach ($tables as $table)
		{
			$newfile .= self::_get_def($table["Tables_in_" . self::$_dbName]);
			$newfile .= "\n";

			if ($table["Tables_in_" . self::$_dbName] == 'cart')
				continue;

			$newfile_data .= self::_get_content($table["Tables_in_" . self::$_dbName]);
			$newfile_data .= "\n";
		}
		self::$_file = self::$_path . '/' . self::$_dbName . '-' . self::$_cur_time . "." . self::$_filetype;
		self::$_filename = self::$_dbName . '-' . self::$_cur_time . "." . self::$_filetype;
		if (!self::_write_backup($newfile, $newfile_data))
			return FALSE;

		// Send backup via email
		return self::_mail_att();
	}

	/**
	 * Create mysqlcode for table-structure
	 * 
	 * @param string $table Name of table to read
	 */
	private static function _get_def($table)
	{
		$result = db::getInstance()->rawQuery("SHOW CREATE TABLE " . $table);

		foreach ($result as $row)
		{
			$def = str_replace("CREATE TABLE", "CREATE TABLE IF NOT EXISTS", $row['Create Table']);
		}

		$def .= " ; ";
		return (stripslashes($def));
	}

	/**
	 * Create mysqlcode for tableentrys
	 * 
	 * @param string $table Name of table to read
	 */
	private static function _get_content($table)
	{
		if ($table == 'cart')
			return "";
		$content = "INSERT INTO `" . $table . "` (";
		$result = db::getInstance()->rawQuery("SHOW COLUMNS FROM " . $table);
		//var_dump($result);exit;
		foreach ($result as $field)
		{
			$content .= "`" . $field['Field'] . "`";
		}
		$content = str_replace("``", "`, `", $content);
		$content .= ") VALUES \n";

		$result = db::getInstance()->rawQuery("SELECT * FROM " . $table);
		$j = 0;

		foreach ($result as $row)
		{
			$j ++;
			// (4, 'Textfeld')
			$content .= "(";

			foreach ($row as $value)
			{
				if ($value != "")
				{
					if (is_numeric($value))
						$content .= addslashes($value) . ", ";
					else
						$content .= "'" . addslashes($value) . "', ";
				}
				else
				{
					$content .= "'', ";
				}
			}
			$content .= ")";
			$content = str_replace(", )", ")", $content);

			if ($j < count($result))
				$content .= ",\n";
		}
		$content .= " ; \n";

		return stripcslashes($content);
	}

	/*
	 * Send backupdata via email (phpmailer)
	 */

	private static function _mail_att()
	{
		// Send mails
		require 'module/class/email/PHPMailerAutoload.php';
		//Create a new PHPMailer instance
		$mail = new PHPMailer();
		$mail->CharSet = 'utf-8';
		$mail->SetLanguage(substr(LANGUAGE, 0, 2));
		//Tell PHPMailer to use SMTP
		$mail->isSMTP();
		$mail->SMTPDebug = SMTP_DEBUG;
		$mail->Debugoutput = 'html';
		$mail->Host = MAIL_HOSTNAME;
		$mail->Port = MAIL_PORT;
		$mail->SMTPAuth = MAIL_AUTH;
		$mail->Username = MAIL_USER;
		$mail->Password = MAIL_PASSWORD;
		$mail->setFrom(MAIL_SENDER, MAIL_SENDER_NAME);

		//Set who the message is to be sent to
		$mail->addAddress(MAIL_RECIVER, '-BACKUP-');
		$mail->addAttachment(self::$_file);
		$mail->Subject = _('Database - Backupdata from') . ' ' . URL;

		$mail->msgHTML(_('As an attachment you can find the backup database information of the domain') .
			' ' . URL);

		if ($mail->send())
		{
			$_SERVER["bmessage"] .= _('Backup file sent successfully.') . '<br>';
		}
		else
		{
			$_SERVER["bmessage"] .= _('Backup file could not be sent!') . '<br>';
			return FALSE;
		}

		if (!unlink(self::$_file))
		{
			message::setErrorRow(_('Backup file on the server could not be deleted'));
			return false;
		}
		else
		{
			$_SERVER["bmessage"] .= _('Deleted backup file on server...') . '<br>';
			$_SERVER["bmessage"] .= _('Completed backup process!') . '<br>';
		}
		return TRUE;
	}

	/*
	 * Save backup on server
	 * 
	 * @param string $newfile			Databasestructur
	 * @param string $newfile_data	Database-data
	 */

	private static function _write_backup($newfile, $newfile_data)
	{
		if (self::$_compression == 1)
		{
			$fp = gzopen(self::$_file, "w9");
			gzwrite($fp, $newfile . $newfile_data);
			gzclose($fp);
		}
		else
		{
			$fp = fopen(self::$_file, "w");
			fwrite($fp, $newfile . $newfile_data);
			fclose($fp);
		}

		if (is_file(self::$_file))
		{
			$_SERVER["bmessage"] .= _('Backupfile createt...') . '<br>';
		}
		else
		{
			$_SERVER["bmessage"] .= _('Backupfile could not createt!') . '<br>';
			return FALSE;
		}
		return TRUE;
	}

	/**
	 * Restore db from uploaded gzip-file
	 * 
	 * @param string $file	Databasefilename
	 */
	public static function startRestore($file)
	{
		// First: delete ALL tables
		$tables = db::getInstance()->rawQuery("SHOW TABLES FROM " . self::$_dbName);

		foreach ($tables as $table)
		{
			db::getInstance()->rawQuery("DROP TABLE " . $table['Tables_in_' . self::$_dbName]);
		}

		$fp1 = gzopen($file, "r");
		$fp2 = fopen($file . '.sql', "w");
		fwrite($fp2, gzread($fp1, 10000000));
		fclose($fp2);
		gzclose($fp1);

		$buffer = file_get_contents($file . '.sql');
		$buffer = str_replace("&#x0;", "", $buffer);
		$sqlQerys = explode(" ; ", $buffer);
		unset($buffer);

		$link = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
		mysqli_set_charset($link, "utf8");

		$err = FALSE;
		foreach ($sqlQerys as $query)
		{
			if (!empty($query))
				mysqli_query($link, $query . ";");
		}

		$_SERVER["bmessage"] .= _('Restore complete.') . '<br>';

		if (unlink($file . '.sql'))
			$_SERVER["bmessage"] .= _('SQL-File deleted.') . '(' . $file . '.sql)<br>';
		else
			$_SERVER["bmessage"] .= _('SQL-File could not deleted.') . '(' . $file . '.sql)<br>';

		if (unlink($file))
			$_SERVER["bmessage"] .= _('Gzip-File deleted.') . '(' . $file . ')<br>';
		else
			$_SERVER["bmessage"] .= _('Gzip-File could not deleted.') . '(' . $file . ')<br>';

		return TRUE;
	}

}

?>